package com.xxl.job.executor.service.jobhandler;

import java.io.*;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.executor.sjbank.pojo.SyContact;
import com.xxl.job.executor.sjbank.pojo.SyCustbill;
import com.xxl.job.executor.sjbank.pojo.model.AwsProperties;
import com.xxl.job.executor.sjbank.service.SyContactService;
import com.xxl.job.executor.sjbank.service.SyCustbillService;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import org.springframework.stereotype.Component;

@Component
public class FtpXxlJob {
    @Value("${sy.ftp.url}")
    private String fUrl;

    @Value("${sy.ftp.port}")
    private int fPort;

    @Value("${sy.ftp.user}")
    private String fUser;

    @Value("${sy.ftp.psw}")
    private String fPsw;

    @Value("${sy.ftp.folder}")
    private String folder;

    @Value("${datafileDir}")
    private String datafileDir;

    @Value("${batchsize}")
    private int batchSize;

    @Value("${filesize}")
    private int fileSize;

    @Value("${executordate}")
    private String executorDate;
    @Resource
    SyCustbillService syCustbillService;
    @Resource
    SyContactService syContactService;

    /**
     * 催收文件下载
     */
    @XxlJob("downloadCollection")
    public void downloadCollection() {
        downloadFile("Collection");
    }

    /**
     * 联系人文件下载
     */
    @XxlJob("downloadContact")
    public void downloadContact() {
        downloadFile("Contact");
    }

    private void downloadFile(String fileName) {
        String month, day, remoteFileOk = null, remoteFile = null, localFile = null, localFileDir;
        LocalDate previousDate = LocalDate.now(ZoneId.of("Asia/Shanghai")).minusDays(1);
        month = previousDate.format(DateTimeFormatter.ofPattern("yyyyMM"));
        day = previousDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        localFileDir = datafileDir + day;
        // 通过 fileName 获取不同的目录
        switch (fileName) {
            case "Collection":
                remoteFileOk = folder + month + "/" + day + ".ok";
                remoteFile = folder + month + "/" + day + ".txt";
                localFile = datafileDir + day + "/" + fileName + ".txt";
                break;
            case "Contact":
                remoteFileOk = folder + month + "/" + day + "_REL.ok";
                remoteFile = folder + month + "/" + day + "_REL.txt";
                localFile = datafileDir + day + "/" + fileName + ".txt";
                break;
        }
        // 调用下载方法
        Download(remoteFileOk, remoteFile, localFile, localFileDir);
    }

    /**
     * 下载文件
     */
    private void Download(String remoteFileOk, String remoteFile, String localFile, String dir) {
        XxlJobHelper.log("远程路径:{} >>>>> 本地路径:{}", remoteFile, localFile);
        FTPClient ftpClient = new FTPClient();
        try {
            // 连接到 FTP 服务器
            ftpClient.connect(fUrl, fPort);
            ftpClient.login(fUser, fPsw);
            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            boolean fileExists = fileExists(ftpClient, remoteFileOk);
            XxlJobHelper.log("fileExists执行结果【.ok文件是否存在】:{}", fileExists);
            if (fileExists) {
                // 确保本地目录存在
                File localFileDir = new File(dir);
                // 尝试创建目录及其父目录
                boolean created = localFileDir.mkdirs();
                if (created) {
                    XxlJobHelper.log("目录创建成功: " + dir);
                } else {
                    if (localFileDir.exists()) {
                        XxlJobHelper.log("目录已存在: " + dir);
                    } else {
                        XxlJobHelper.log("目录创建失败: " + dir);
                    }
                }

                try (FileOutputStream fos = new FileOutputStream(localFile)) {
                    // 下载文件
                    boolean success = ftpClient.retrieveFile(remoteFile, fos);
                    if (success) {
                        XxlJobHelper.log("文件下载成功!");
                    } else {
                        XxlJobHelper.log("文件下载失败!");
                    }
                }
            } else {
                XxlJobHelper.log(".ok文件不存在！");
            }
        } catch (IOException e) {
            XxlJobHelper.log("(Download)IO错误:" + e);
        } finally {
            try {
                // 断开连接
                if (ftpClient.isConnected()) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                }
            } catch (IOException e) {
                XxlJobHelper.log("(Download【finally】)IO错误:" + e);
            }
        }
    }

    // 检查远程文件是否存在
    private boolean fileExists(FTPClient ftpClient, String remoteFilePath) throws IOException {
        // 获取远程文件所在的目录
        String parentDir = remoteFilePath.substring(0, remoteFilePath.lastIndexOf('/'));
        String fileName = remoteFilePath.substring(remoteFilePath.lastIndexOf('/') + 1);
        XxlJobHelper.log("（检查远程FTP.ok文件是否存在）远程目录:{} >>>>> 文件名称:{}", parentDir, fileName);
        // 切换到父目录
        if (ftpClient.changeWorkingDirectory(parentDir)) {
            // 获取该目录下的所有文件
            FTPFile[] files = ftpClient.listFiles();
            for (FTPFile file : files) {
                if (file.getName().equals(fileName)) {
                    return true;  // 找到文件，返回true
                }
            }
        }
        return false;  // 没有找到文件，返回false
    }

    /**
     * 删除历史文件
     */
    @XxlJob("DeleteFile")
    public void DeleteFile() {
        String date = LocalDate.now(ZoneId.of("Asia/Shanghai")).minusDays(3).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        Path directory = Paths.get(datafileDir + date);
        XxlJobHelper.log("DeleteFile: 删除的目录" + directory);

        try (Stream<Path> paths = Files.walk(directory)) {
            paths.sorted(Comparator.reverseOrder())  // 确保先删除文件和子文件夹
                    .forEach(path -> {
                        try {
                            XxlJobHelper.log("DeleteFile:" + path + " >>>> 已删除");
                            Files.delete(path);  // 删除文件或文件夹
                        } catch (IOException e) {
                            XxlJobHelper.log("DeleteFile: 删除失败 " + path + ": " + e.getMessage());
                        }
                    });
            XxlJobHelper.log("DeleteFile: 目录删除成功");
        } catch (IOException e) {
            XxlJobHelper.log("IOException: " + e.getMessage());
        }
    }

    /**
     * 获取文件地址
     */
    public List<String> fileList() {
        String date = LocalDate.now(ZoneId.of("Asia/Shanghai")).minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        Path dirPath = Paths.get(datafileDir + date);
        //Path dirPath = Paths.get(datafileDir);
        try (Stream<Path> paths = Files.list(dirPath)) {
            List<String> fileList = paths
                    .filter(Files::isRegularFile)
                    .filter(path -> !path.getFileName().toString().startsWith(".")) // 排除以.开头的隐藏文件
                    .map(Path::toString)
                    .collect(Collectors.toList());
            // 打印所有文件路径
            fileList.forEach(XxlJobHelper::log);
            return fileList;
        } catch (IOException e) {
            //e.printStackTrace();
            XxlJobHelper.log("(fileList函数)错误日志:" + e);
        }
        return new ArrayList<>();
    }

    /**
     * 手动文件卸数
     */
    @XxlJob("ManualReadFileWToDb")
    public void ManualReadFileWToDb() {
        XxlJobHelper.log("手动执行文件卸数不校验文件数量");
        ReadFileWToDb("Manual");
    }

    /**
     * 自动文件卸数
     */
    @XxlJob("AutoReadFileWToDb")
    public void AutoReadFileWToDb() {
        XxlJobHelper.log("自动执行文件卸数");
        ReadFileWToDb("Auto");
    }

    /**
     * 文件卸数
     */
    private void ReadFileWToDb(String opt) {
        String date = LocalDate.now(ZoneId.of("Asia/Shanghai")).minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        List<BufferedReader> readers = new ArrayList<>();
        try {
            List<String> fileList = fileList();
            XxlJobHelper.log("当日文件总数量: " + fileList.size());
            if (fileList.size() > fileSize || Objects.equals(opt, "Manual")) {
                DeleteMiddleTable();
                // 初始化每个 BufferedReader 实例
                for (String file : fileList) {
                    readers.add(new BufferedReader(new FileReader(file)));
                    //XxlJobHelper.log("Reader实例: " + readers);
                }
                for (int i = 0; i < readers.size(); i++) {
                    BufferedReader reader = readers.get(i);
                    //XxlJobHelper.log("Reading file: " + fileList.get(i) + ", 对应Reader实例: " + reader);
                    XxlJobHelper.log("Reading file: " + fileList.get(i));
                    String substring = fileList.get(i).substring(fileList.get(i).lastIndexOf('/') + 1);
                    String tableName = substring.substring(0, substring.indexOf('.'));
                    XxlJobHelper.log("Writing file: " + tableName);

                    switch (tableName) {
                        case "Collection":
                            WSyTables(reader);
                            break;
                        case "Contact":
                            WSyContTables(reader);
                            break;
                    }
                    // 关闭 BufferedReader
                    reader.close();
                }
            } else {
                XxlJobHelper.log("当日文件总数:{}数量小于2", fileList.size());
            }
        } catch (IOException e) {
            //e.printStackTrace();
            XxlJobHelper.log("错误日志:" + e);
        } finally {
            // 确保所有 BufferedReader 都被关闭
            for (BufferedReader reader : readers) {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        //e.printStackTrace();
                        XxlJobHelper.log("BufferedReader.close时,错误日志:" + e);
                    }
                }
            }
        }
    }

    /**
     * 清空表中间表
     */
    public void DeleteMiddleTable() {
        XxlJobHelper.log("清空中间表开始>>>>>>>>>");
        syCustbillService.remove(new QueryWrapper<>());
        syContactService.remove(new QueryWrapper<>());
        XxlJobHelper.log("清空中间表结束>>>>>>>>>");
    }

    private void WSyTables(BufferedReader reader) {
        String line = null;
        List<SyCustbill> cBList = new ArrayList<>();
        List<SyContact> cTList = new ArrayList<>();
        Date Crdt = new Date();
        try {
            while ((line = reader.readLine()) != null) {
                //line = line.trim(); // 修剪行
                String[] parts = line.split("\\|", -1);
                //XxlJobHelper.log("parts: " + Arrays.toString(parts));
                //XxlJobHelper.log("parts.length: " + parts.length);
                //XxlJobHelper.log("line: " + line);
                if (parts.length < 68) {
                    XxlJobHelper.log("<<<当前数据不符合规范列>>>: " + Arrays.toString(parts));
                    XxlJobHelper.log("当前length: " + parts.length);

                    StringBuilder strBuilder = new StringBuilder(line);

                    // 不断读取下一行并拼接，直到 parts.length >= 68
                    while (parts.length < 68) {
                        String nextLine = reader.readLine();
                        XxlJobHelper.log("拼接下一行数据: " + nextLine);
                        strBuilder.append(nextLine); // 拼接下一行
                        parts = strBuilder.toString().split("\\|", -1); // 重新分割拼接后的行
                        XxlJobHelper.log("拼接后length: " + parts.length);
                    }
                }
                if (parts.length <= 69) {
                    SyCustbill syCustbill = new SyCustbill();
                    syCustbill.setStore(parts[0].trim());
                    syCustbill.setMerchant(parts[1].trim());
                    syCustbill.setCustid(parts[2].trim());
                    syCustbill.setSnum(parts[3].trim());
                    syCustbill.setCustname(parts[4].trim());
                    syCustbill.setOpenacctcerttype(parts[5].trim());
                    syCustbill.setOpenacctcertno(parts[6].trim());
                    syCustbill.setGender(parts[7].trim());
                    syCustbill.setContactphone(parts[8].trim());
                    syCustbill.setPhone(parts[9].trim());
                    syCustbill.setProvince(parts[10].trim());
                    syCustbill.setCity(parts[11].trim());
                    syCustbill.setDistrict(parts[12].trim());
                    syCustbill.setNameWork(parts[13].trim());
                    syCustbill.setProvinceWork(parts[14].trim());
                    syCustbill.setCityWork(parts[15].trim());
                    syCustbill.setDistrictWork(parts[16].trim());
                    syCustbill.setAddressWork(parts[17].trim());
                    syCustbill.setPhoneWork(parts[18].trim());
                    syCustbill.setProvinceFamily(parts[19].trim());
                    syCustbill.setCityFamily(parts[20].trim());
                    syCustbill.setDistrictFamily(parts[21].trim());
                    syCustbill.setAddressFamily(parts[22].trim());
                    syCustbill.setPhoneFamily(parts[23].trim());
                    syCustbill.setMarrgstatus(parts[24].trim());
                    syCustbill.setHeightedudegr(parts[25].trim());
                    syCustbill.setNameSpouse(parts[26].trim());
                    syCustbill.setPhoneSpouse(parts[27].trim());
                    syCustbill.setWorkSpouse(parts[28].trim());
                    syCustbill.setApplydt(parts[29].trim());
                    syCustbill.setApplyprin(parts[30].trim());
                    syCustbill.setApplyid(parts[31].trim());
                    syCustbill.setProductnum(parts[32].trim());
                    syCustbill.setBillid(parts[33].trim());
                    syCustbill.setLoadamt(parts[34].trim());
                    syCustbill.setLoadrate(parts[35].trim());
                    syCustbill.setLoadstartdt(parts[36].trim());
                    syCustbill.setLoadenddt(parts[37].trim());
                    syCustbill.setContractodue(parts[38].trim());
                    syCustbill.setRepaydate(parts[39].trim());
                    syCustbill.setLendingbank(parts[40].trim());
                    syCustbill.setIsmths(parts[41].trim());
                    syCustbill.setIssettle(parts[42].trim());
                    syCustbill.setIsin(parts[43].trim());
                    syCustbill.setMthsodue(parts[44].trim());
                    syCustbill.setLoanbalance(parts[45].trim());
                    syCustbill.setOverduePrin(parts[46].trim());
                    syCustbill.setOverdueTotal(parts[47].trim());
                    syCustbill.setOverdueDt(parts[48].trim());
                    syCustbill.setPaymtclrd(parts[49].trim());
                    syCustbill.setOverdueInte(parts[50].trim());
                    syCustbill.setRate(parts[51].trim());
                    syCustbill.setOverdueIntp(parts[52].trim());
                    syCustbill.setFee(parts[53].trim());
                    syCustbill.setRepayno(parts[54].trim());
                    syCustbill.setEntrychannel(parts[55].trim());
                    syCustbill.setEntrysubchannel(parts[56].trim());
                    syCustbill.setLoantype(parts[57].trim());
                    syCustbill.setLoansubtype(parts[58].trim());
                    syCustbill.setIsjointloan(parts[59].trim());
                    syCustbill.setLoanparty(parts[60].trim());
                    syCustbill.setMarkchanneltype(parts[61].trim());
                    syCustbill.setContractid(parts[62].trim());
                    syCustbill.setFivelevel(parts[63].trim());
                    syCustbill.setBillacctstatus(parts[64].trim());
                    syCustbill.setLastrepaydt(parts[65].trim());
                    syCustbill.setLastrepayprin(parts[66].trim());
                    syCustbill.setAddress(parts[67].trim());
                    syCustbill.setAction("0");

                    String mthsStr = parts[48].trim();
                    if (!mthsStr.isEmpty()) {
                        LocalDate currentDate = LocalDate.now();
                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                        LocalDate overdueDate = LocalDate.parse(mthsStr, formatter);
                        long overdueDay = currentDate.toEpochDay() - overdueDate.toEpochDay();
                        //XxlJobHelper.log("parts.48: " + parts[48].trim() + " >>>>> overdueDay:" + overdueDay);
                        syCustbill.setMthsday((int) overdueDay);
                        int overdueMonths = (int) Math.ceil(overdueDay / 30.0);
                        syCustbill.setMthsodues(overdueMonths);
                        //XxlJobHelper.log(" >>>>> overdueMonths:" + overdueMonths);
                    }
                    syCustbill.setCrdt(Crdt);
                    cBList.add(syCustbill);

                    String contStr = parts.length > 68 ? parts[68].trim() : "";
                    if (!contStr.isEmpty()) {
                        String[] contacts = contStr.split("##");
                        //XxlJobHelper.log("data>>>>> " + Arrays.toString(contacts));

                        for (String contact : contacts) {
                            // 处理每个 contact
                            String[] fields = contact.split("\\$\\$");
                            //XxlJobHelper.log("contact>>>>> " + contact);
                            //XxlJobHelper.log("fields>>>>> " + Arrays.toString(fields) + ">>>" + fields.length);

                            SyContact syContact = new SyContact();
                            if (fields.length > 0 && !fields[0].trim().isEmpty()) {
                                syContact.setContactname(fields[0].trim());
                            }
                            if (fields.length > 1 && !fields[1].trim().isEmpty()) {
                                syContact.setContacttype(fields[1].trim());
                            }
                            if (fields.length > 2 && !fields[2].trim().isEmpty()) {
                                syContact.setContactphone(fields[2].trim());
                            }
                            if (fields.length > 3 && !fields[3].trim().isEmpty()) {
                                syContact.setAddress(fields[3].trim());
                            }
                            syContact.setCustid(parts[2].trim());
                            syContact.setAction("0");
                            syContact.setCrdt(Crdt);
                            cTList.add(syContact);

                            if (cTList.size() >= batchSize) {
                                syContactService.saveBatch(cTList);
                                XxlJobHelper.log("Contact Inserted batch of size: " + cTList.size());
                                cTList.clear();
                            }
                        }
                    }

                    if (cBList.size() >= batchSize) {
                        syCustbillService.saveBatch(cBList);
                        XxlJobHelper.log("CustBill Inserted batch of size: " + cBList.size());
                        cBList.clear();
                    }
                } else {
                    XxlJobHelper.log("拼接后依然不符合规范列: " + Arrays.toString(parts));
                }
            }
            // 插入剩余的记录
            if (!cTList.isEmpty()) {
                syContactService.saveBatch(cTList);
                XxlJobHelper.log("Contact Inserted final batch of size: " + cTList.size());
            }
            if (!cBList.isEmpty()) {
                syCustbillService.saveBatch(cBList);
                XxlJobHelper.log("CustBill Inserted final batch of size: " + cBList.size());
            }
        } catch (Exception e) {
            XxlJobHelper.log("XXL-JOB-SyTables, 错误日志:" + e + ">>>>>【异常行】:" + line);
        }
    }

    private void WSyContTables(BufferedReader reader) {
        String line = null;
        List<SyContact> cTList = new ArrayList<>();
        Date Crdt = new Date();
        try {
            while ((line = reader.readLine()) != null) {
                String[] parts = line.split("\\|", -1);
                SyContact syContact = new SyContact();
                syContact.setCustid(parts[0].trim());
                syContact.setEvnumber(parts[1].trim());
                syContact.setContactname(parts[2].trim());
                syContact.setContactphone(parts[3].trim());
                syContact.setContacttype(parts[4].trim());
                syContact.setAction("0");
                syContact.setCrdt(Crdt);
                cTList.add(syContact);

                if (cTList.size() >= batchSize) {
                    syContactService.saveBatch(cTList);
                    XxlJobHelper.log("Contact Inserted batch of size: " + cTList.size());
                    cTList.clear();
                }
            }
            // 插入剩余的记录
            if (!cTList.isEmpty()) {
                syContactService.saveBatch(cTList);
                XxlJobHelper.log("Contact Inserted final batch of size: " + cTList.size());
            }
        } catch (Exception e) {
            XxlJobHelper.log("XXL-JOB-WSyContTables, 错误日志:" + e + ">>>>>【异常行】:" + line);
        }
    }


    private AmazonS3 s3Client;
    @Autowired
    AwsProperties aws;

    @PostConstruct
    public void init() {
        s3Client = initClient(aws);
    }

    public void FilmsUtils(AwsProperties aws) {
        this.aws = aws;
    }

    /**
     * 初始化client
     *
     * @return
     */
    private AmazonS3 initClient(AwsProperties aws) {
        AmazonS3 s3client = null;
        // 设置连接时的参数
        ClientConfiguration config = new ClientConfiguration();
        // 设置连接方式为HTTP，可选参数为HTTP和HTTPS
        config.setProtocol(Protocol.HTTP);
        // config.setProtocol(Protocol.HTTPS);
        // 设置网络访问超时时间
        config.setConnectionTimeout(30000);
        config.setUseExpectContinue(true);
        // 获取访问凭证
        AWSCredentials credentials = null;
        credentials = new BasicAWSCredentials(aws.getAkey(), aws.getSkey());
        // 设置Endpoint
        EndpointConfiguration end_point = null;
        end_point = new AwsClientBuilder.EndpointConfiguration(aws.getEndpoint(), "");
        // 创建连接
        s3client = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(credentials))
                .withClientConfiguration(config).withEndpointConfiguration(end_point).withPathStyleAccessEnabled(true)
                .build();
        return s3client;
    }

    /**
     * 下载文件（手动执行）
     */
    @XxlJob("AwsDownloadManual")
    public void AwsDownloadManual() {
        String[] tables = {
                "iol_icms_custr_a",
                "iol_icms_cnta_a",
                "iol_icms_addr_a",
                "iol_icms_acct_a",
                "iol_icms_accx_a",
                "iol_icms_card_a",
                "iol_icms_mpur_a",
                "iol_icms_clocd_a",
                "iol_icms_prmcn_a",
                "iol_icms_ddac_a",
                "iol_icms_stma_a",
                "iol_icms_event_a",
                "iol_icms_cuplg_a",
                "icl_mtc_cuindvinfo_cs",
                "icl_mtc_cuaddrinfo_cs",
                "icl_mtc_evloaninfo_cs",
                "icl_mtc_evplaninfo_cs",
                "icl_mtc_evtrsainfo_cs"
        };

        for (String table : tables) {
            String keyOk = executorDate + "/iel/" + table + "." + executorDate + ".ok";
            String keyDat = executorDate + "/iel/" + table + "." + executorDate + ".dat";
            String path = datafileDir + "/" + executorDate + "/" + table + "." + executorDate + ".dat";

            XxlJobHelper.log("下载参数:【keyOk】:{} >>>>【keyDat】:{} >>>>【path】:{}", keyOk, keyDat, path);
            Boolean okExists = objExists(keyOk);
            XxlJobHelper.log("objExists执行结果【{}.ok文件是否存在】:{}", table, okExists);

            if (okExists) {
                Boolean datExist = FilDownload(keyDat, path);
                XxlJobHelper.log("Download执行结果【{}.dat文件是否存在】:{}", table, datExist);
            }
        }
    }

    /**
     * 下载文件
     */
    @XxlJob("AwsDownload")
    public void AwsDownload() {
        String date = LocalDate.now(ZoneId.of("Asia/Shanghai")).minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String[] tables = {
                "iol_icms_custr_a",
                "iol_icms_cnta_a",
                "iol_icms_addr_a",
                "iol_icms_acct_a",
                "iol_icms_accx_a",
                "iol_icms_card_a",
                "iol_icms_mpur_a",
                "iol_icms_clocd_a",
                "iol_icms_prmcn_a",
                "iol_icms_ddac_a",
                "iol_icms_stma_a",
                "iol_icms_event_a",
                "iol_icms_cuplg_a",
                "icl_mtc_cuindvinfo_cs",
                "icl_mtc_cuaddrinfo_cs",
                "icl_mtc_evloaninfo_cs",
                "icl_mtc_evplaninfo_cs",
                "icl_mtc_evtrsainfo_cs"
        };

        for (String table : tables) {
            String keyOk = date + "/iel/" + table + "." + date + ".ok";
            String keyDat = date + "/iel/" + table + "." + date + ".dat";
            String path = datafileDir + "/" + date + "/" + table + "." + date + ".dat";

            XxlJobHelper.log("下载参数:【keyOk】:{} >>>>【keyDat】:{} >>>>【path】:{}", keyOk, keyDat, path);
            Boolean okExists = objExists(keyOk);
            XxlJobHelper.log("objExists执行结果【{}.ok文件是否存在】:{}", table, okExists);

            if (okExists) {
                Boolean datExist = FilDownload(keyDat, path);
                XxlJobHelper.log("Download执行结果【{}.dat文件是否存在】:{}", table, datExist);
            }
        }
    }

    private Boolean FilDownload(String key, String localPath) {
        //S3Object fullObject = null, objectPortion = null, headerOverrideObject = null;
        S3Object fullObject = null;
        // 该 key 的对象必须已经在集群中存在，否则报错 NoSuchKey
        if (!objExists(key)) {
            return false;
        }
        try {
            XxlJobHelper.log("Downloading an object by key : " + key);
            // 获取对象
            fullObject = s3Client.getObject(new GetObjectRequest(aws.getBucketName(), key));
            s3Client.getObject(new GetObjectRequest(aws.getBucketName(), key), new File(localPath));

        } catch (AmazonServiceException e) {
            // 服务端错误
            XxlJobHelper.log("服务端错误:" + e);
        } catch (AmazonClientException e) {
            // 客户端错误
            XxlJobHelper.log("客户端错误:" + e);
        } finally {
            // 为了确保网络连接断开，请关闭任何打开的输入流
            try {
                if (fullObject != null) {
                    fullObject.close();
                }
//                if (objectPortion != null) {
//                    objectPortion.close();
//                }
//                if (headerOverrideObject != null) {
//                    headerOverrideObject.close();
//                }
            } catch (IOException e) {
                XxlJobHelper.log("IO错误:" + e);
                return false;
            }
        }
        return objExists(key);
    }

    private Boolean objExists(String key) {
        return s3Client.doesObjectExist(aws.getBucketName(), key);
    }

    private static BigDecimal parseBigDecimalOrZero(String str) {
        if (str.isEmpty()) {
            return BigDecimal.ZERO;
        } else {
            try {
                return new BigDecimal(str);
            } catch (NumberFormatException e) {
                XxlJobHelper.log("无法将字符串转换为BigDecimal: " + str);
                return BigDecimal.ZERO;
            }
        }
    }

}
